/*
 * Rust基础数据类型教程 - 案例13：字符串转浮点
 * 
 * 本案例演示如何将字符串转换为浮点数，包括：
 * 1. parse()方法的使用
 * 2. 错误处理机制
 * 3. 不同浮点类型的解析
 * 4. 特殊值的处理
 * 5. 实际应用场景
 */

fn main() {
    println!("=== Rust 字符串转浮点数教程 ===\n");
    
    // 1. 基础字符串转换
    basic_parsing();
    
    // 2. 类型明确指定
    explicit_type_parsing();
    
    // 3. 错误处理
    error_handling();
    
    // 4. 特殊值处理
    special_values();
    
    // 5. 实际应用案例
    practical_examples();
    
    // 6. 批量处理
    batch_processing();
    
    // 7. 自定义解析函数
    custom_parsing_functions();
}

/// 1. 基础字符串转换示例
/// 演示最基本的字符串到浮点数的转换
fn basic_parsing() {
    println!("1. 基础字符串转换");
    println!("{}", "-".repeat(40));
    
    // 使用parse()方法进行转换
    // 语法：string.parse::<类型>()
    let s1 = "3.14";
    let f1: f64 = s1.parse().unwrap(); // 类型推断
    println!("字符串 \"{}\" 转换为 f64: {}", s1, f1);
    
    let s2 = "2.71828";
    let f2: f32 = s2.parse().unwrap(); // 指定为f32类型
    println!("字符串 \"{}\" 转换为 f32: {}", s2, f2);
    
    // 直接指定类型的方式
    let f3 = "1.234".parse::<f64>().unwrap();
    println!("直接指定类型转换: {}", f3);
    
    // 负数转换
    let negative = "-123.456".parse::<f64>().unwrap();
    println!("负数转换: {}", negative);
    
    println!();
}

/// 2. 类型明确指定
/// 展示不同的类型指定方式
fn explicit_type_parsing() {
    println!("2. 类型明确指定");
    println!("{}", "-".repeat(40));
    
    let number_str = "42.5";
    
    // 方式1：变量声明时指定类型
    let f32_value: f32 = number_str.parse().unwrap();
    let f64_value: f64 = number_str.parse().unwrap();
    
    println!("f32 值: {} (内存: 4字节)", f32_value);
    println!("f64 值: {} (内存: 8字节)", f64_value);
    
    // 方式2：parse方法中指定类型
    let explicit_f32 = number_str.parse::<f32>().unwrap();
    let explicit_f64 = number_str.parse::<f64>().unwrap();
    
    println!("显式指定 f32: {}", explicit_f32);
    println!("显式指定 f64: {}", explicit_f64);
    
    // 方式3：函数调用时指定
    display_parsed_number::<f32>(number_str);
    display_parsed_number::<f64>(number_str);
    
    println!();
}

/// 泛型函数用于演示类型指定
fn display_parsed_number<T>(s: &str) 
where 
    T: std::str::FromStr + std::fmt::Display,
    <T as std::str::FromStr>::Err: std::fmt::Debug,
{
    match s.parse::<T>() {
        Ok(value) => println!("泛型解析成功: {}", value),
        Err(e) => println!("泛型解析失败: {:?}", e),
    }
}

/// 3. 错误处理
/// 演示各种错误情况和处理方式
fn error_handling() {
    println!("3. 错误处理");
    println!("{}", "-".repeat(40));
    
    // 使用unwrap() - 遇到错误会panic
    println!("使用unwrap()方法 (注意：错误会导致程序崩溃):");
    let valid_str = "123.45";
    let result = valid_str.parse::<f64>().unwrap();
    println!("成功解析: {}", result);
    
    // 使用match进行错误处理
    println!("\n使用match进行安全的错误处理:");
    let test_strings = vec!["123.45", "not_a_number", "12.34.56", "", " 123.45 "];
    
    for s in test_strings {
        match s.parse::<f64>() {
            Ok(value) => println!("\"{}\" -> {} (成功)", s, value),
            Err(e) => println!("\"{}\" -> 解析错误: {} (失败)", s, e),
        }
    }
    
    // 使用if let进行简化处理
    println!("\n使用if let简化错误处理:");
    let maybe_number = "67.89";
    if let Ok(num) = maybe_number.parse::<f64>() {
        println!("解析成功: {}", num);
    } else {
        println!("解析失败");
    }
    
    // 使用unwrap_or提供默认值
    println!("\n使用unwrap_or提供默认值:");
    let invalid_str = "invalid";
    let default_value = invalid_str.parse::<f64>().unwrap_or(0.0);
    println!("解析失败时使用默认值: {}", default_value);
    
    // 使用unwrap_or_else动态生成默认值
    let default_with_closure = invalid_str.parse::<f64>().unwrap_or_else(|_| -1.0);
    println!("解析失败时使用闭包生成默认值: {}", default_with_closure);
    
    println!();
}

/// 4. 特殊值处理
/// 演示无穷大、NaN等特殊浮点值的解析
fn special_values() {
    println!("4. 特殊值处理");
    println!("{}", "-".repeat(40));
    
    // 正无穷大
    let pos_inf = "inf".parse::<f64>().unwrap();
    println!("正无穷大: {} (is_infinite: {})", pos_inf, pos_inf.is_infinite());
    
    let pos_infinity = "infinity".parse::<f64>().unwrap();
    println!("正无穷大(完整): {} (is_infinite: {})", pos_infinity, pos_infinity.is_infinite());
    
    // 负无穷大
    let neg_inf = "-inf".parse::<f64>().unwrap();
    println!("负无穷大: {} (is_infinite: {})", neg_inf, neg_inf.is_infinite());
    
    // NaN (Not a Number)
    let nan_value = "NaN".parse::<f64>().unwrap();
    println!("NaN: {} (is_nan: {})", nan_value, nan_value.is_nan());
    
    // 科学计数法
    let scientific1 = "1.23e4".parse::<f64>().unwrap();
    println!("科学计数法 1.23e4: {}", scientific1);
    
    let scientific2 = "5.67E-3".parse::<f64>().unwrap();
    println!("科学计数法 5.67E-3: {}", scientific2);
    
    let scientific3 = "-2.5e+10".parse::<f64>().unwrap();
    println!("科学计数法 -2.5e+10: {}", scientific3);
    
    // 检测特殊值的函数
    println!("\n特殊值检测:");
    check_special_value(pos_inf);
    check_special_value(neg_inf);
    check_special_value(nan_value);
    check_special_value(42.0);
    
    println!();
}

/// 检测浮点数是否为特殊值
fn check_special_value(value: f64) {
    print!("值 {}: ", value);
    if value.is_nan() {
        println!("这是 NaN");
    } else if value.is_infinite() {
        if value.is_sign_positive() {
            println!("这是正无穷大");
        } else {
            println!("这是负无穷大");
        }
    } else if value.is_finite() {
        println!("这是有限数值");
    } else {
        println!("未知类型");
    }
}

/// 5. 实际应用案例
/// 演示字符串转浮点数在实际场景中的应用
fn practical_examples() {
    println!("5. 实际应用案例");
    println!("{}", "-".repeat(40));
    
    // 模拟从配置文件读取数值
    println!("场景1: 配置文件解析");
    let config_data = vec![
        ("temperature_threshold", "25.5"),
        ("timeout_seconds", "30.0"),
        ("pi_approximation", "3.14159"),
    ];
    
    for (key, value) in config_data {
        match parse_config_value(value) {
            Some(num) => println!("配置项 {}: {}", key, num),
            None => println!("配置项 {} 解析失败: {}", key, value),
        }
    }
    
    // 模拟用户输入处理
    println!("\n场景2: 用户输入验证");
    let user_inputs = vec!["12.34", "0", "-5.67", "abc", "12.34.56"];
    
    for input in user_inputs {
        match validate_user_input(input) {
            Ok(value) => println!("用户输入 \"{}\" 有效: {}", input, value),
            Err(msg) => println!("用户输入 \"{}\" 无效: {}", input, msg),
        }
    }
    
    // 计算平均值示例
    println!("\n场景3: 成绩平均值计算");
    let score_strings = vec!["85.5", "92.0", "78.5", "88.0", "95.5"];
    match calculate_average(&score_strings) {
        Ok(avg) => println!("成绩平均值: {:.2}", avg),
        Err(e) => println!("计算失败: {}", e),
    }
    
    println!();
}

/// 解析配置值
fn parse_config_value(value: &str) -> Option<f64> {
    value.parse().ok()
}

/// 验证用户输入
fn validate_user_input(input: &str) -> Result<f64, String> {
    match input.parse::<f64>() {
        Ok(value) => {
            if value.is_finite() {
                Ok(value)
            } else {
                Err("输入值不是有限数".to_string())
            }
        },
        Err(_) => Err("输入格式不正确".to_string()),
    }
}

/// 计算字符串数组的平均值
fn calculate_average(strings: &[&str]) -> Result<f64, String> {
    let mut sum = 0.0;
    let mut count = 0;
    
    for s in strings {
        match s.parse::<f64>() {
            Ok(value) => {
                sum += value;
                count += 1;
            },
            Err(_) => return Err(format!("无法解析 \"{}\"", s)),
        }
    }
    
    if count == 0 {
        Err("没有有效数据".to_string())
    } else {
        Ok(sum / count as f64)
    }
}

/// 6. 批量处理
/// 演示批量字符串转换的处理方式
fn batch_processing() {
    println!("6. 批量处理");
    println!("{}", "-".repeat(40));
    
    let number_strings = vec![
        "1.1", "2.2", "3.3", "invalid", "4.4", "5.5", "NaN", "6.6"
    ];
    
    // 方法1: 过滤有效值
    println!("方法1: 过滤有效值");
    let valid_numbers: Vec<f64> = number_strings
        .iter()
        .filter_map(|s| s.parse().ok())
        .collect();
    println!("有效数字: {:?}", valid_numbers);
    
    // 方法2: 分离成功和失败
    println!("\n方法2: 分离成功和失败");
    let (successes, failures): (Vec<_>, Vec<_>) = number_strings
        .iter()
        .map(|s| (s, s.parse::<f64>()))
        .partition(|(_, result)| result.is_ok());
    
    let success_values: Vec<f64> = successes
        .into_iter()
        .map(|(_, result)| result.unwrap())
        .collect();
    
    let failure_strings: Vec<&str> = failures
        .into_iter()
        .map(|(s, _)| *s)
        .collect();
    
    println!("成功解析: {:?}", success_values);
    println!("解析失败: {:?}", failure_strings);
    
    // 方法3: 统计处理结果
    println!("\n方法3: 统计处理结果");
    let mut success_count = 0;
    let mut failure_count = 0;
    let mut total_sum = 0.0;
    
    for s in &number_strings {
        match s.parse::<f64>() {
            Ok(value) if value.is_finite() => {
                success_count += 1;
                total_sum += value;
            },
            Ok(_) => {
                // 特殊值如NaN, infinity
                println!("跳过特殊值: {}", s);
            },
            Err(_) => {
                failure_count += 1;
            }
        }
    }
    
    println!("总数: {}", number_strings.len());
    println!("成功: {}", success_count);
    println!("失败: {}", failure_count);
    if success_count > 0 {
        println!("有效数值平均值: {:.2}", total_sum / success_count as f64);
    }
    
    println!();
}

/// 7. 自定义解析函数
/// 展示如何创建更灵活的解析函数
fn custom_parsing_functions() {
    println!("7. 自定义解析函数");
    println!("{}", "-".repeat(40));
    
    // 容错解析函数
    println!("容错解析（自动清理空白字符）:");
    let messy_strings = vec![" 123.45 ", "\t67.89\n", " -12.34 ", "  0.0  "];
    for s in messy_strings {
        match parse_with_cleanup(s) {
            Ok(value) => println!("\"{}\" -> {}", s, value),
            Err(e) => println!("\"{}\" -> 错误: {}", s, e),
        }
    }
    
    // 带单位的解析
    println!("\n带单位的数值解析:");
    let values_with_units = vec!["123.45kg", "67.89m", "25.5°C", "100%"];
    for s in values_with_units {
        match parse_with_unit(s) {
            Some((value, unit)) => println!("\"{}\" -> 数值: {}, 单位: {}", s, value, unit),
            None => println!("\"{}\" -> 解析失败", s),
        }
    }
    
    // 多格式解析
    println!("\n多格式数值解析:");
    let various_formats = vec!["123.45", "1,234.56", "1_234.56", "$123.45"];
    for s in various_formats {
        match parse_flexible(s) {
            Ok(value) => println!("\"{}\" -> {}", s, value),
            Err(e) => println!("\"{}\" -> 错误: {}", s, e),
        }
    }
    
    println!();
}

/// 带清理功能的解析函数
fn parse_with_cleanup(s: &str) -> Result<f64, std::num::ParseFloatError> {
    s.trim().parse()
}

/// 解析带单位的数值
fn parse_with_unit(s: &str) -> Option<(f64, String)> {
    // 找到第一个非数字非小数点非负号字符的位置
    let mut split_pos = 0;
    for (i, c) in s.char_indices() {
        if !c.is_ascii_digit() && c != '.' && c != '-' && c != '+' && c != 'e' && c != 'E' {
            split_pos = i;
            break;
        }
    }
    
    if split_pos == 0 {
        return None;
    }
    
    let (number_part, unit_part) = s.split_at(split_pos);
    match number_part.parse::<f64>() {
        Ok(value) => Some((value, unit_part.to_string())),
        Err(_) => None,
    }
}

/// 灵活的解析函数，支持多种格式
fn parse_flexible(s: &str) -> Result<f64, String> {
    // 移除常见的非数字字符
    let cleaned = s
        .replace(",", "")  // 移除千位分隔符
        .replace("_", "")  // 移除下划线分隔符
        .replace("$", ""); // 移除美元符号
    
    cleaned.parse::<f64>()
        .map_err(|e| format!("解析错误: {}", e))
}
